// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "AbilitySystemInterface.h"
#include "GameFramework/Character.h"
#include "Interaction/CombatInterface.h"
#include "BaseCharacter.generated.h"

class UNiagaraSystem;
class UGameplayAbility;
class UGameplayEffect;
class UAttributeSet;
class UAbilitySystemComponent;


UCLASS(Abstract)
class AURA_API ABaseCharacter : public ACharacter, public IAbilitySystemInterface, public ICombatInterface
{
	GENERATED_BODY()

public:

	ABaseCharacter();

	// ----------------------------------------------------------------------------------------------------------------
	//	ASC
	// ----------------------------------------------------------------------------------------------------------------

	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
	virtual UAttributeSet* GetAttributeSet() const;

	// ----------------------------------------------------------------------------------------------------------------
	//	ICombatInterface 接口
	// ----------------------------------------------------------------------------------------------------------------

	virtual FVector GetCombatSocketLocation_Implementation() const override;
	virtual UAnimMontage* GetHitReactMontage_Implementation() const override;
	virtual AActor* GetAvatar_Implementation() override;
	virtual bool IsDead_Implementation() const override;
	virtual void Die() override;
	virtual TArray<FTaggedMontage> GetAttackMontages_Implementation() const override;
	/** 通过蒙太奇封装结构体判断当前是否使用武器攻击，如果使用武器攻击，则从武器上面获取插槽位置，反之，则从角色模型身上获取插槽位置。 */
	virtual FVector GetCombatSocketLocationByStruct_Implementation(const FTaggedMontage& TaggedMontage) const override;
	virtual UNiagaraSystem* GetBloodEffect_Implementation() const override;
	virtual FTaggedMontage GetTaggedMontageByTag_Implementation(const FGameplayTag& MontageTag) const override;
	virtual FVector GetCombatSocketLocationByTag_Implementation(
		const FGameplayTag SocketTag, const FName& SocketName
	) const override;
	virtual int32 GetMinionsCount_Implementation() override;
	virtual void IncrementMinionsCount_Implementation(const int32 Amount) override;
	virtual ERoleClass GetRoleClass_Implementation() const override;
	virtual int32 GetLevel() override;
	// ----------------------------------------------------------------------------------------------------------------
	//	其他
	// ----------------------------------------------------------------------------------------------------------------

	/** 角色类型 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="ABaseCharacter|Character Class Defaults")
	ERoleClass RoleClass = ERoleClass::Warrior;

	/** 等级 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="ABaseCharacter|Character Class Defaults")
	int32 Level = 1;

protected:

	virtual void BeginPlay() override;

	// ----------------------------------------------------------------------------------------------------------------
	//	组件
	// ----------------------------------------------------------------------------------------------------------------

	/** 武器骨骼网格体指针 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ABaseCharacter|Combat")
	TObjectPtr<USkeletalMeshComponent> Weapon = nullptr;

	/** 能力系统组件指针 */
	UPROPERTY()
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent = nullptr;

	/** 属性集指针 */
	UPROPERTY()
	TObjectPtr<UAttributeSet> AttributeSet = nullptr;

	// ----------------------------------------------------------------------------------------------------------------
	//	战斗相关
	// ----------------------------------------------------------------------------------------------------------------

	/** 死亡音效 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ABaseCharacter|Combat")
	TObjectPtr<USoundBase> DeathSound = nullptr;
	
	/** 受伤特效指针 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ABaseCharacter|Combat")
	TObjectPtr<UNiagaraSystem> BloodEffect = nullptr;
	
	/** 攻击蒙太奇 */
	UPROPERTY(EditAnywhere, Category="ABaseCharacter|Combat")
	TArray<FTaggedMontage> AttackMontages;

	/** 仆从数量 */
	UPROPERTY(BlueprintReadOnly, Category="ABaseCharacter|Combat")
	int32 MinionsCount = 0;

	/** 是否死亡标志位 */
	bool bDead = false;

	/** 被命中反应蒙太奇指针 */
	UPROPERTY(EditAnywhere, Category="ABaseCharacter|Combat")
	TObjectPtr<UAnimMontage> HitReactMontage = nullptr;

	/** 武器插槽名称,用于获取发射投射物时武器插槽位置 */
	UPROPERTY(EditAnywhere, Category = "ABaseCharacter|Combat")
	FName WeaponTipSocketName;

	/** 溶解材质实例指针 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ABaseCharacter|Combat")
	TObjectPtr<UMaterialInstance> DissolveMaterialInstance = nullptr;

	/** 武器溶解材质实例指针 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ABaseCharacter|Combat")
	TObjectPtr<UMaterialInstance> WeaponDissolveMaterialInstance = nullptr;

	/** 溶解 */
	void Dissolve();

	/** 启动溶解动画 */
	UFUNCTION(BlueprintImplementableEvent)
	void StartDissolveTimeline(const TArray<UMaterialInstanceDynamic*>& DynamicMaterialInstances);

	/** 网络广播死亡 */
	UFUNCTION(NetMulticast, Reliable)
	virtual void MulticastHandleDeath();

	// ----------------------------------------------------------------------------------------------------------------
	//	初始化相关
	// ----------------------------------------------------------------------------------------------------------------

	/** 初始化属性 */
	virtual void InitDefaultAttributes() const;

	/** 初始化能力相关Actor信息 */
	virtual void InitAbilityActorInfo() {}
	
	/** 控制某些属性是否在当前类或子类面板中出现 */
	UPROPERTY()
	bool bShowProps = true;

	/** GE类,用于初始化默认主要属性 */
	UPROPERTY(EditAnywhere, Category= "ABaseCharacter|Default Attribute", meta = (EditCondition = "bShowProps", EditConditionHides))
	TSubclassOf<UGameplayEffect> DefaultPrimaryAttributeEffectClass;

	/** GE类,用于初始化次要属性 */
	UPROPERTY(EditAnywhere, Category= "ABaseCharacter|Default Attribute", meta = (EditCondition = "bShowProps", EditConditionHides))
	TSubclassOf<UGameplayEffect> DefaultSecondaryAttributeEffectClass;

	/** GE类,用于初始化重要属性 */
	UPROPERTY(EditAnywhere, Category= "ABaseCharacter|Default Attribute", meta = (EditCondition = "bShowProps", EditConditionHides))
	TSubclassOf<UGameplayEffect> DefaultVitalAttributeEffectClass;
	
	// ----------------------------------------------------------------------------------------------------------------
	//	其他
	// ----------------------------------------------------------------------------------------------------------------
};
